package com.fingard.dsp.bank.directbank.spdb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBalanceCheck;
import com.fingard.dsp.bank.directbank.spdb01.authforrec.StringUtils;
import com.fingard.dsp.bank.reqrespobj.balancecheck.ReqBalCheckQry;
import com.fingard.dsp.bank.reqrespobj.balancecheck.RetAtsBalCheckQry;
import com.fingard.dsp.bank.reqrespobj.balancecheck.detail.RetAtsBalCheckDetail;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import java.util.Date;

public class SPDB01BalanceCheck extends SPDB01Base implements IBalanceCheck {
    @Override
    public RetAtsBalCheckQry d_7508_BalCheck(ReqBalCheckQry p_req7508) throws Exception {
        //返回给Ats的响应
        RetAtsBalCheckQry retAts = new RetAtsBalCheckQry(p_req7508.reqHeader, p_req7508.actNum);
        //Ats响应通用报文头
        retAts.writeStart();
        try {
            /**
             * 确定查询个数
             */
            int totalNum = -1;//账单总个数
            int nowNum = 1;//目前查询到的账单个数
            do {
                /**
                 * （1）dsp 报文无确定的账单编号字段，先用FW47进行模糊查询
                 */
                SPDB01Header tmpBnkHeader = new SPDB01Header();
                tmpBnkHeader.transCode = "FW47";
                XmlTextWriter fw47Writer = new XmlTextWriter();
                //报文主体
                fw47Writer.writeStartElement("body");
                fw47Writer.writeElementString("checkNo", "");//账单编号 非必填
                fw47Writer.writeElementString("transMasterID", bankFront.org);//交易客户号
                fw47Writer.writeElementString("acctNo", p_req7508.actNum);//账号  已签约为MD51为主账号  未签约可以填客户下的任一账号
                fw47Writer.writeElementString("checkType", "");//账单类型代码 0-纸质，1-电子 为空时默认电子账单
                fw47Writer.writeElementString("checkStatus", "");//账单状态  0-可不对账;1-未对账;2-已对账
                Date dateFrom = p_req7508.getYearMonth();
                fw47Writer.writeElementString("beginDate", Format.Date8Format.format(formatFirstOfMonth(dateFrom)));//开始日期 YYYYMMDD  当月的第一天
                fw47Writer.writeElementString("endDate", Format.Date8Format.format(formatEndOfMonth(dateFrom)));    //结束日期 YYYYMMDD  当月的最后一天  开始日期和截止日期不超过一年
                fw47Writer.writeElementString("beginNumber", nowNum + "");//起始笔数
                fw47Writer.writeElementString("queryNumber", "50");//查询笔数  最大50 超过默认50
                fw47Writer.writeEndDocument();
                //发送至银行接口
                String[] tmpRetBkStr = sendToBank(fw47Writer.toXmlString(), tmpBnkHeader);

                if (tmpRetBkStr[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                        String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                        if ("AAAAAAA".equals(returnCode)) {
                            //总个数
                            totalNum = Integer.valueOf(tmpBkReader.getFirstText("/packet/body/totalNumber"));
                            while (tmpBkReader.read("/packet/body/list")) {
                                //每一个账单新建一个detail对象，用于存储每一笔账单的详细信息
                                RetAtsBalCheckDetail p_retDetail = new RetAtsBalCheckDetail();
                                XElement fw47info = tmpBkReader.readedXElement;
                                String checkNo = fw47info.getSingleTextNotNull("checkNo");//账单编号
                                String transMasterID = fw47info.getSingleTextNotNull("transMasterID");//交易客户号
                                String acctNo = fw47info.getSingleText("acctNo");//账号
                                String checkStatus = fw47info.getSingleTextNotNull("checkStatus");//账单状态  0-可不对账;1-未对账;2-已对账
                                String detailStatus = fw47info.getSingleTextNotNull("detailStatus");//明细状态 0-已生成 1-已发出 2-未送达 3-未回收 4-已回收验印不符 5-对账相符 6-余额不符 7-调节后相符 8-可不对账此明细状态为主账号明细状态
                                String checkType = fw47info.getSingleTextNotNull("checkType");//账单类型代码 0-纸质，1-电子
                                String checkDate = fw47info.getSingleTextNotNull("checkDate");//账单日期
                                //(2)将获取到的账单时间信息加入到fp99中进行查询
                                fp99_deal(acctNo, checkDate, checkType, checkStatus, detailStatus, p_retDetail);
                                /**
                                 * 开始填充p_retDetail的内容
                                 */
                                p_retDetail.actNum = acctNo;//账号
                                p_retDetail.actName = "";//户名 todo
                                p_retDetail.statementNumber = checkNo;//对账单编号
                                p_retDetail.yearMonth = checkDate.substring(0,6);//对账年月 只取年和月
                                p_retDetail.cltNbr = transMasterID;//客户号
                                //对账类型，
                                // 浦发：0-纸质，1-电子
                                // dsp: E电子对账，P纸质对账
                                p_retDetail.stmType = "0".equals(checkType) ? "P" : "1".equals(checkType) ? "E" : "";
                                //处理状态，
                                // 浦发：0-已生成 1-已发出 2-未送达 3-未回收 4-已回收验印不符 5-对账相符 6-余额不符 7-调节后相符 8-可不对账
                                // dsp: 1已生成数据，2对账完成，4对账中   新增 8 可不对账
                                int detailStatusNumber = Integer.parseInt(detailStatus);
                                if (detailStatusNumber == 0) {
                                    p_retDetail.dealState = "1";
                                } else if (1 <= detailStatusNumber && detailStatusNumber <= 4) {
                                    p_retDetail.dealState = "4";
                                } else if(detailStatusNumber == 8){
                                    p_retDetail.dealState = "8";//todo 新增 8 可不对账
                                }else {
                                    p_retDetail.dealState = "2";
                                }
                                retAts.writeRetDetail(p_retDetail);
                                nowNum++;
                            }
                        } else {
                            retAts = new RetAtsBalCheckQry(p_req7508.reqHeader, p_req7508.actNum);
                            retAts.writeStart();//写返回ATS的统一头部信息
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo(returnMsg);
                        }
                    } else {
                        retAts = new RetAtsBalCheckQry(p_req7508.reqHeader, p_req7508.actNum);
                        retAts.writeStart();//写返回ATS的统一头部信息
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpSbMsg.toString());
                    }
                } else {
                    retAts = new RetAtsBalCheckQry(p_req7508.reqHeader, p_req7508.actNum);
                    retAts.writeStart();//写返回ATS的统一头部信息
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpRetBkStr[1]);
                }
            } while (nowNum <= totalNum);
        } catch (Exception ex) {
            retAts = new RetAtsBalCheckQry(p_req7508.reqHeader, p_req7508.actNum);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(ex.getMessage());
            this.WriteBankLogLn(ex);
        }
        retAts.writeEnd();
        return retAts;

    }

    /**
     * fp99进行对账单详细信息查询
     *
     * @param acctNo       账号  若客户已签约MD51，则输入签约时主账号；若客户未签约MD51，则可输入待查询账号 账号必须在银企直连柜面签约YQDZ功能
     * @param checkDate    账期 YYYYMMDD FW47返回明细中的账单日期
     * @param checkChannel -电子/0-纸质PDF 为空默认电子
     * @param checkStatus  查询明细状态为8的明细
     *                     1-未对账
     *                     查询明细状态为0-4的明细
     *                     <p>
     *                     2-已对账
     *                     查询明细状态为5-7的明细
     * @param detailStatus 明细状态 0-已生成 1-已发出 2-未送达 3-未回收 4-已回收验印不符 5-对账
     */
    private void fp99_deal(String acctNo, String checkDate, String checkChannel, String checkStatus, String detailStatus, RetAtsBalCheckDetail p_retDetail) throws Exception {
        SPDB01Header tmpBnkHeader = new SPDB01Header();
        tmpBnkHeader.transCode = "FP99";

        int totalNum = -1;//账单总个数
        int nowNum = 1;//目前查询到的账单个数
        do {
            XmlTextWriter fp99Writer = new XmlTextWriter();

            fp99Writer.writeStartElement("body");
            fp99Writer.writeElementString("acctNo", acctNo);
            fp99Writer.writeElementString("checkDate", checkDate);
            fp99Writer.writeElementString("checkChannel", checkChannel);
            fp99Writer.writeElementString("checkStatus", checkStatus);
            fp99Writer.writeElementString("detailStatus", detailStatus);
            fp99Writer.writeElementString("beginNumber", nowNum + "");//起始笔数查询
            fp99Writer.writeElementString("queryNumber", "50");//查询笔数  最大50
            fp99Writer.writeEndDocument();

            //发送至银行接口
            String[] tmpRetBkStr = sendToBank(fp99Writer.toXmlString(), tmpBnkHeader);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if ("AAAAAAA".equals(returnCode)) {
                        //逻辑一：若已签约MD51拥有主账号，则将全部账号的账单信息提取出来
//                    String mainAcctNo = tmpBkReader.getFirstText("/packet/body/acctNo");//获取主账号
//                    if(StringUtils.isNotEmpty(mainAcctNo) && mainAcctNo.equals(acctNo)){
//
//                    }
                        //逻辑二：只筛选dsp得到的账号，不管是不是主账号  目前使用逻辑二
                        totalNum = Integer.valueOf(tmpBkReader.getFirstText("/packet/body/totalNumber"));
                        while (tmpBkReader.read("/packet/body/lists/list")) {
                            XElement fp99Element = tmpBkReader.readedXElement;
                            String subAcctNo = fp99Element.getSingleTextNotNull("subAcctNo");//账号  MD51签约时，交易客户号下所有账号
                            //若输入的账号和查询到的账号匹配，则筛选出来
                            if (StringUtils.isNotEmpty(subAcctNo) && subAcctNo.equals(acctNo)) {
                                String currency = fp99Element.getSingleTextNotNull("currency");//币种 人民币RMB
                                String acctProperty = fp99Element.getSingleTextNotNull("acctProperty");//账户属性 1-活期 2-活期保证金 3-定期 4-通知存款 5-协议存款 6-定期保证金 7-贷款 8-对公按揭 9-贷款欠息 10-公司卡 11-集团委贷
                                String bankBalance = fp99Element.getSingleTextNotNull("bankBalance");//银行余额
                                String companyBalance = fp99Element.getSingleTextNotNull("companyBalance");//企业余额 当“企业余额”有值时，表示该数值为客户上次核对不符时客户所输入的金额。如“企业余额”无值时，表示该客户上次未核对到不符的情况

                                p_retDetail.actBal = bankBalance;//账户余额
                                /**
                                 * 币种
                                 */
                                p_retDetail.actCur = getBankConfig().getMapKeyByValue("currencyMapping", currency);
                                /**
                                 * 存款种类
                                 * 浦发：1-活期 2-活期保证金3-定期4-通知存款5-协议存款6-定期保证金7-贷款8-对公按揭9-贷款欠息 10-公司卡 11-集团委贷
                                 * dsp: 1往来户,2贷款户,3定期户,4保证金户，5内部户，6个人贷款综合账户，9其他，34定期保证金户
                                 */
                                if ("1".equals(acctProperty)) {
                                    p_retDetail.acctType = "1";
                                } else if ("2".equals(acctProperty)) {
                                    p_retDetail.acctType = "4";
                                } else if ("3".equals(acctProperty)) {
                                    p_retDetail.acctType = "3";
                                } else if ("6".equals(acctProperty)) {
                                    p_retDetail.acctType = "34";
                                } else if ("7".equals(acctProperty)) {
                                    p_retDetail.acctType = "2";
                                } else {
                                    p_retDetail.acctType = "9";
                                }
                                /**
                                 * 余额审核状态
                                 * 浦发：0-已生成 1-已发出 2-未送达 3-未回收 4-已回收验印不符 5-对账相符 6-余额不符 7-调节后相符 8-可不对账
                                 * dsp: 1未对账,2平(余额相符),3不平(余额不符),6纸质回收成功,7调节相符,8忽略,9强制忽略
                                 */
                                int detailStatusNumber = Integer.parseInt(detailStatus);

                                if (detailStatusNumber <= 4) {
                                    p_retDetail.dzFlag = "1";
                                } else if (detailStatusNumber == 5) {
                                    p_retDetail.dzFlag = "2";
                                } else if (detailStatusNumber == 6) {
                                    p_retDetail.dzFlag = "3";
                                } else if (detailStatusNumber == 7) {
                                    p_retDetail.dzFlag = "7";
                                } else {
                                    p_retDetail.dzFlag = "8";
                                }
                                break;//todo 此处要求fp99应答的循环中必须账号唯一，否则只能取同一账号的第一条数据。
                            } else {
                                nowNum++;
                                continue;
                            }
                        }
                    } else {
                        throw new Exception("fp99出现异常:" + returnMsg);
                    }
                } else {
                    throw new Exception("fp99出现异常:" + tmpSbMsg.toString());
                }
            } else {
                throw new Exception("fp99出现异常:" + tmpRetBkStr[1]);
            }
        } while (nowNum <= totalNum);
    }
}
